package com.hitqz.robot.biz.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.hitqz.robot.api.common.entity.MapArea;
import com.hitqz.robot.api.common.entity.MapAreaPos;
import com.hitqz.robot.api.common.entity.RobotMap;
import com.hitqz.robot.api.business.model.param.mapArea.MapAreaPosParams;
import com.hitqz.robot.api.business.model.param.mapArea.AddMapAreaParams;
import com.hitqz.robot.api.business.model.vo.mapArea.MapAreaVo;
import com.hitqz.robot.biz.service.MapAreaPosService;
import com.hitqz.robot.biz.service.MapAreaService;
import com.hitqz.robot.biz.service.RobotMapService;
import com.hitqz.robot.common.core.util.R;
import com.hitqz.robot.driver.model.PointDto;
import com.hitqz.robot.driver.parent.RobotDriverService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;

/**
 * @author xupkun
 * @date 2024/5/30
 */

@RestController
@AllArgsConstructor
@RequestMapping("/mapArea")
@Tag(name = "区域管理")
@Slf4j
public class MapAreaController {

    private final MapAreaService mapAreaService;

    private final MapAreaPosService mapAreaPosService;

    private final RobotMapService robotMapService;

    private final RobotDriverService robotDriverService;

    private final ExecutorService customThreadPool;


    @GetMapping
    @Operation(summary = "获取地图所有的区域")
    public R<List<MapAreaVo>> getArea(@Parameter(description = "地图编码") @RequestParam(value = "mapCode") String mapCode,
                                      @Parameter(description = "区域名称") @RequestParam(value = "name", required = false) String name) {
        List<MapArea> mapAreas = mapAreaService.list(Wrappers.<MapArea>lambdaQuery()
                .eq(MapArea::getMapCode, mapCode)
                .like(StrUtil.isNotBlank(name), MapArea::getName, name)
        );
        List<MapAreaVo> vos = Lists.newArrayList();
        for (MapArea area : mapAreas) {
            MapAreaVo vo = new MapAreaVo();
            BeanUtil.copyProperties(area, vo);
            vo.setLightStatus(0);
            vo.setMapPath(robotMapService.getOne(Wrappers.<RobotMap>lambdaQuery().eq(RobotMap::getMapCode, mapCode)).getFilePath());
            List<MapAreaPos> pos = mapAreaPosService.list(Wrappers.<MapAreaPos>lambdaQuery().eq(MapAreaPos::getAreaId, vo.getId()));
            List<MapAreaPosParams> params = Lists.newArrayList();
            for (MapAreaPos p  : pos) {
                MapAreaPosParams posParams = new MapAreaPosParams();
                BeanUtil.copyProperties(p, posParams);
                params.add(posParams);
            }
            vo.setMapName(robotMapService.findByMapCode(vo.getMapCode()).getMapName());
            vo.setPosList(params);
            vos.add(vo);
        }
        return R.ok(vos);
    }

    @PostMapping
    @Operation(summary = "添加区域")
    public R add(@RequestBody AddMapAreaParams params) {
        MapArea mapArea= new MapArea();
        params.setId(null);
        BeanUtil.copyProperties(params, mapArea);
        mapArea.setId(null);
        mapAreaService.save(mapArea);
        mapAreaPosService.remove(Wrappers.<MapAreaPos>lambdaQuery().eq(MapAreaPos::getAreaId, params.getId()));
        RobotMap robotMap = robotMapService.findByMapCode(params.getMapCode());
        for (MapAreaPosParams posParams : params.getAreaPos()) {
            MapAreaPos mapAreaPos= new MapAreaPos();
            PointDto pointDto = new PointDto();
            pointDto.setX(posParams.getCanvasPosx());
            pointDto.setY(posParams.getCanvasPosy());
            PointDto calPos = robotDriverService.canvas2Point(robotMap, pointDto);

            BeanUtil.copyProperties(posParams, mapAreaPos);
            mapAreaPos.setAreaId(mapArea.getId());
            mapAreaPos.setId(null);
            mapAreaPos.setStatus(1);
            mapAreaPos.setPosx(calPos.getX());
            mapAreaPos.setPosy(calPos.getY());
            mapAreaPos.setYaw(0.0);
            mapAreaPosService.save(mapAreaPos);
        }
        this.syncMapArea();
        return R.ok();
    }

    @PutMapping
    @Operation(summary = "更新区域")
    public R update(@RequestBody AddMapAreaParams params) {
        MapArea mapArea= new MapArea();
        BeanUtil.copyProperties(params, mapArea);
        mapAreaService.updateById(mapArea);
        if (CollUtil.isNotEmpty(params.getAreaPos())) {
            mapAreaPosService.remove(Wrappers.<MapAreaPos>lambdaQuery().eq(MapAreaPos::getAreaId, params.getId()));
            for (MapAreaPosParams posParams : params.getAreaPos()) {
                MapAreaPos mapAreaPos= new MapAreaPos();
                BeanUtil.copyProperties(posParams, mapAreaPos);
                mapAreaPos.setAreaId(params.getId().longValue());
                mapAreaPosService.save(mapAreaPos);
            }
        }
        this.syncMapArea();
        return R.ok();
    }


    @DeleteMapping
    @Operation(summary = "删除区域")
    public R delete(@RequestBody Integer[] ids) {
        for(Integer id : ids) {
            mapAreaService.removeById(id);
            mapAreaPosService.remove(Wrappers.<MapAreaPos>lambdaQuery().eq(MapAreaPos::getAreaId, id));
        }
        this.syncMapArea();
        return R.ok();
    }

    @GetMapping("syncMapArea")
    @Operation(summary = "同步区域数据")
    public R syncMapArea() {
        CompletableFuture.runAsync(mapAreaService::asyncMapArea,customThreadPool);
        CompletableFuture.runAsync(mapAreaService::initMapArea,customThreadPool);
        return R.ok();
    }

}
